import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 东莞呵呵
 * Date:2022-06-22
 * Time:14:44
 */
public class MergeSort {
    public static void mergeSort(int[] array) {
        mergeSortInternal(array, 0, array.length - 1);//-1数组长度和high差一
    }

    //递归版本
    public static void mergeSortInternal(int[] array, int low, int high) {
        if (low >= high) {
            return;
        }
        int mid = (low + high) / 2;
        mergeSortInternal(array, low, mid);
        mergeSortInternal(array, mid + 1, high);
        merge(array, low, high, mid);
    }

    public static void merge(int[] array, int low, int high, int mid) {
        int s1 = low;
        int e1 = mid;
        int s2 = mid + 1;
        int e2 = high;
        int[] tmp = new int[high - low + 1];
        int k = 0;
        while (s1 <= e1 && s2 <= e2) {
            if (array[s1] <= array[s2]) {//加上=就变成稳定的排序
                tmp[k++] = array[s1++];
            } else {
                tmp[k++] = array[s2++];
            }
        }
        while (s1 <= e1) {
            tmp[k++] = array[s1++];
        }
        while (s2 <= e2) {
            tmp[k++] = array[s2++];
        }
        for (int i = 0; i < tmp.length; i++) {
            array[low + i] = tmp[i];
        }
    }

    //非递归版本
    public static void mergeSort2(int[] array) {
        int nums = 1;
        while (nums < array.length) {
            for (int i = 0; i < array.length; i += nums * 2) {
                int left = i;
                int mid = left + nums - 1;
                if (mid >= array.length) {
                    mid = array.length - 1;
                }
                int right = mid + nums;
                if (right >= array.length) {
                    right = array.length - 1;
                }
                merge(array,left,right,mid);
            }
            nums*=2;
        }
    }

    public static void main(String[] args) {
        int[] arr = {65, 43, 5, 7, 4, 5, 76, 23, 4, 765, 42, 6, 7, 8};
        mergeSort2(arr);
        System.out.println(Arrays.toString(arr));
    }
}
